home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-11 | 14.6 KB | 354 lines | [TEXT/PJMM] |
-
- { THIS IS AN EXAMPLE OF A PROGRAM WRITTEN USING A SUBCLASS OF xWindow TO }
- { IMPLEMENT A SIMPLE TEXT EDITOR PROGRAM. NOTE THAT THE SUBCLASS }
- { xFileTextWindow CONTAINS FILE-MANIPULATION PROCEDURES, AND THAT }
- { COMMANDS HAVE BEEN ADDED TO THE FILE MENU THAT USE THESE PROCEDURES. }
- { THE RESOURCE FILE ALSO CONTAINS OTHER RESOURCES REQUIRED IN ADDITION }
- { TO THE USUSAL ONES USED BY xWindows AND StandardMain. }
-
- { This file is a modified version of the file applicationProcs.p. Most of the comments from }
- { the original file are still here. }
-
- { This sample program requires modified resources in the file TextPrint.rsrc, rather }
- { than the resource file generic.rsrc used by the project generic.π. }
-
- { This unit would be a natural starting point for a program that uses small text files }
- { and also uses windows of other types. You could simply declare and use other window }
- { types as appopriate. }
-
-
- unit applicationProcs;
-
- interface
-
- uses
- xWindow, xTextWindow, xFileTextWindow, PrintTraps, TextPrint;
- { I have omitted xControlDecoration and xWindowDecoration, which are }
- { not used in this sample program. And I have added several other UNITs }
- { that are used. }
- { To use any of the other units that define subclasses of xWindow and }
- { of xWindowDecoration, you must add them here. (If one of the units uses }
- { definitions from other units, the one that USES the definitions must follow }
- { the one that contains the definition.) }
-
- const
-
- maxSleepTime = 5; { When the main program has no events to process, it "goes to }
- { sleep" and yields processing time to other processes that may be running. }
- { However, this program still wants to process "idle" events. The constant }
- { maxSleepTime specifies the longest time this program is willing to sleep }
- { between idle events. The time is specified in ticks (60 ticks = 1 second), so }
- { a value of 5 corresponds to about 12 idle events per second, which is OK for }
- { most purposes. However, if you are using idle events to drive a processing }
- { task (such as drawing successive pieces of a graph on each idle event), you }
- { can change this value, setting it as low as 0 if you like, in which case the }
- { Mac will give as little time as possible to other processes. }
-
-
- { The constants defined below are used by the main program to set up the "About }
- { Box" that is displayed when the user chooses "About . . . " from the apple menu. }
- { Change them as appropriate for the program you are writing. }
-
- ApplicationShortName = 'Simple Edit';
- { This is the name of the program displayed in the first line of the Apple }
- { Menu. In this example, "About Simple Edit..." will appear there. }
-
- ApplicationLongName = 'A Simple Text Editor program';
- { Provides a fuller description of the program that will be displayed at the }
- { top of the "About Box". }
-
- AuthorName = 'David Eck';
- AuthorAddress1 = 'Hobart and William Smith Colleges';
- AuthorAddress2 = 'Geneva, NY 14456';
- AuthorAddress3 = '(Email Address: eck@hws.BITNET)';
- { These four items are displayed on the next four lines of the About Box, under }
- { the heading "Created By:" You can, of course, leave some of these empty, or }
- { use some of them for information other than an address. }
-
- CommentLine = 'This demonstration text editing program can edit only short text files.';
- { This line is simply displayed at the bottom of the about box. }
-
- var
- editMenu: MenuHandle; { These two variables provide references to the File and }
- fileMenu: MenuHandle; { Edit menus. The main program requires that they be here. }
-
-
- { The following list of procedures is called by the main program. You should not}
- { remove or change the name or parameter list for any of these procedures. If your }
- { program does not require one of these procedures, just leave its definition blank. }
-
- procedure InitializeApplication;
- { Called when the program is first starting up; use this procedure to initialize }
- { any global variables, open any windows that you want to appear automatically }
- { on the screen at startup, etc. }
-
- procedure CleanUpApplication;
- { This is called just before the program ends, to give you a final chance to clean }
- { up. Most programs will have no use for this. There is no way to abort program }
- { termination from this procedure. }
-
- procedure DoEditMenu (itemNum: integer);
- { The user has chosen the specified item number from the Edit menu. This }
- { procedure should carry out that command. (Items in menus are numbered }
- { from the top down, starting with 1. Separating lines in the menu are numbered}
- { even though they are not really commands.) }
-
- procedure DoFileMenu (itemNum: integer;
- var done: boolean);
- { Perform command number "itemNum" from the File Menu; if the user has chosen }
- { the Quit command, then the parameter "done" should be set to TRUE, unless }
- { the command is canceled in one way or another (for example, if you put up a }
- { dialog box that says "Do you really want to quit?" and the user answers No). }
- { In this sample program, the comands are New, Open, Save, Save As, Close, }
- { and Quit, with dividing line between Close and Quit. }
-
- procedure DoOtherMenu (menuNum, itemNum: integer);
- { This procedure is here just in case you add more menus to the menu bar. The }
- { user has selected item number "itemNum" from menu number "menuNum", }
- { and this procedure should carry out that command. Note that the menu number }
- { used here is the menu ID (or resource number), not the position of the menu in }
- { the menu bar. }
-
- procedure UpdateMenus;
- { This procedure is called just BEFORE the user makes a selection from the }
- { menu bar, after the user has clicked in the menu bar, but before any menu is }
- { displayed. Use this procedure to enable and disable items in the menu, to set }
- { the names of items with changeable names, to check and uncheck items, etc. }
-
- procedure ApplicationIdle;
- { This procedure is called periodically--at least six times a second, unless the }
- { computer is otherwise occupied (for example, tied up in a lengthy computation). }
- { Note that for text windows, this procedure is used to blink the insertion point }
- { in the active window. This is done when an idle message is sent to the front }
- { window. }
-
- implementation
-
-
- {------------------Outline of defintion of new window class.----------------}
-
- { NOTE: The class myWin is not used in this sample program. However, its definition is }
- { included here as a basis for including other windows in programs you might write }
- { based on this one. (This is just a copy of the stuff from my standard applicationProcs.p }
-
-
- type
-
- { To write your own application, you will probably declare one or more new window }
- { classes as subclasses of xWindow or of one of its existing subclasses. }
- { Here, a class myWin is defined which overrides several of the procedures from the }
- { parent class. These procedures are the ones that would most commonly have to }
- { be overriden to create a new class. Other procedures that you might commonly want }
- { to override include: idle, doClose, doHScroll, doVScroll. See the defintion of the }
- { class xWindow and its sub-classes for more information. }
- { In a more realistic example, you would very probably have one or more instance }
- { variables in your window class to hold any data pertinent to a particular window, }
- { (for example, an array representing the contents of a checkers board). }
-
- myWin = object(xWindow)
- procedure setDefaults;
- override;
- procedure openInRect (title: string;
- left, top, right, bottom: integer);
- override;
- procedure doRedraw (badRect: Rect);
- override;
- procedure doContentClick (localPt: Point;
- modifiers: longint);
- override;
- procedure doKey (ch: char;
- modifiers: longint);
- override;
- end;
-
- { Next, give the definitions of these overriden procedures. }
-
- procedure myWin.setDefaults;
- { This procedure sets up the defalut appearance of the window, and initializes certain }
- { instance variables. It is called BEFORE the window is opened, by openInRect. }
- begin
- inherited setDefaults;
- end;
-
- procedure myWin.openInRect (title: string;
- left, top, right, bottom: integer);
- { The purpose of this procedure is to open a window, initialize its data structures, etc. }
- { The title is displayed in the title bar of the window; the position and size of the }
- { window are determined by the remaining parameters. (top,left) is the point at the }
- { top, left corner of the inside part of the window, and (right,bottom) is the bottom }
- { right corner. Ordinarily, this procedure is called by procedure Open, instead of }
- { being used directly. }
- begin
- inherited openInRect(title, left, top, right, bottom);
- end;
-
-
- procedure myWin.doRedraw (badRect: Rect);
- { This procedure is called when all or part of the stuff in the window needs to be }
- { redrawn. The parameter badRect specifies the region of the window that needs to }
- { be redrawn; the usual thing to do is to just ignore it and to redraw the entire }
- { window. }
- { This procedure is called, for example, when another window that has been }
- { covering this one is moved or closed. By default, it is also called when the user }
- { changes the position of the scroll bar. In both cases, the widow is erased before }
- { the procedure is called. (Erasing and redrawing the window may not be the effect }
- { you want when the window is scrolled; to change this default behaviour, you have }
- { to override the procedures doHScroll and doVScroll.) }
- { The default method in xWindow for doRedraw redraws any }
- { xWindowDecorations in the Window. Some subclasses of xWindow have }
- { other responses to the message doContentClick. Unless you are sure you }
- { have no reason to do so, you sould call INHERITED doContentClick in addition }
- { to any other redrawing you do for your window. }
- begin
- inherited doRedraw(badRect); { ordinarily, you should call this somewhere in your procedure }
- end;
-
-
- procedure myWin.doContentClick (localPt: Point;
- modifiers: longint);
- { This procedure is called when the user clicks on the "content region" of the }
- { window. (If the user clicks on the scroll bar, title bar, or grow box, that is }
- { handled automatically; this procedure is not called in such cases.) The point }
- { where the user clicked is given by the parameter localPt. (The point is in "local }
- { coordinates," i.e. is specified relative to the top left corner of the window.) }
- { The parameter modifiers can be used to check whether the shift, command or }
- { option keys were held down when the mouse was clicked. This sample program }
- { does not respond to clicks. }
- { The default method in xWindow for doContentClick sends the doClick to any appropriate }
- { xWindowDecoration in the Window. Some subclasses of xWindow have }
- { other responses to the message doContentClick. Unless you are sure you }
- { have no decorations in your window, you sould call INHERITED doContentClick }
- { whenever your procedure does not handle the click itself. }
- begin
- inherited doContentClick(localPt, modifiers);
- end;
-
-
- procedure myWin.doKey (ch: char;
- modifiers: longint);
- { This procedure is called when the user presses a key, provided this is the front }
- { (or "active") window. This procedure is not used by the sample program. }
- { The default method in xWindow for doKey sends a doKey message to any appropriate }
- { xWindowDecoration in the Window. Some subclasses of xWindow have }
- { other responses to the message doKey. Unless you want some other response }
- { to a key, you sould call INHERITED doKey . }
- begin
- inherited doKey(ch, modifiers)
- end;
-
-
- procedure OpenAWindow;
- { A very common procedure is one for opening a new window; not used in this sample program! }
- var
- Win: myWin;
- begin
- new(Win);
- Win.open('Sample Window');
- end;
-
-
-
-
- {------------- Definitions of procedures called by the main program, or ------------}
- {-----------------------used in the sample edit program---------------------}
-
-
- procedure InitializeApplication;
- { initialize unit xTextFileWindow, and open an initial editting window. }
- begin
- InitTextFileWindows;
- PrintDataRecord := nil; { from unit TextPrint }
- doNewCommand; { from unit xTextFileWindow }
- end;
-
- procedure CleanUpApplication;
- { no clean up necessary in this program }
- begin
- end;
-
- procedure ApplicationIdle;
- { send idle message to front window, it there is one and if it is an xWindow }
- var
- win: WindowPtr;
- X: xWindow;
- begin
- win := FrontWindow;
- if (win <> nil) & (Window2xWindow(win, X)) then
- X.idle; { blinks cursor in text window }
- end;
-
- procedure UpdateMenus;
- var
- win: WindowPtr;
- X: xWindow;
- { enable and disable menu items, as appropriate }
- begin
- twUpdateEditMenu(editMenu); { from UNIT xTextWindow }
- UpdateFileMenu(fileMenu); { from UNIT xFileTextWindow }
- win := FrontWindow;
- if (win <> nil) & (Window2xWindow(win, X)) & member(x, xTextWindow) then
- EnableItem(fileMenu, 7)
- else
- DisableItem(FileMenu, 7);
- end;
-
- procedure doPrintCommand;
- var
- win: WindowPtr;
- X: xWindow;
- theText: CharsHandle;
- str: string;
- begin
- win := FrontWindow;
- if (win <> nil) & (Window2XWindow(win, X)) & (member(X, xTextWindow)) then begin
- theText := xTextWindow(X).GetText;
- str := X.GetTitle;
- str := StringOf(str, ', \d, \t\r Page \p');
- PrintText(theText, GetHandleSize(Handle(theText)), str, geneva, 12, 0);
- end;
- end;
-
- procedure DoFileMenu (itemNum: integer;
- var done: boolean);
- begin { commands are sent to procedures in unit xTextFileWindow }
- case itemNum of
- 1:
- doNewCommand;
- 2:
- doOpenCommand;
- 3:
- doSaveCommand;
- 4:
- doSaveAsCommand;
- 5:
- doCloseCommand;
- 7:
- doPrintCommand;
- 8:
- doPageSetup;
- 10:
- CloseAllBeforeQuitting(done);
- end;
- end;
-
- procedure DoEditMenu (itemNum: integer);
- { command is sent to the front window, if it is an xTextWindow (as it has to be }
- { in this sample program, if there is any active window at all) }
- var
- win: windowPtr;
- xWin: xWindow;
- begin
- win := FrontWindow;
- if win <> nil then begin
- xWin := xWindow(WindowPeek(win)^.refCon);
- if (xWin <> nil) & member(xWin, xTextWindow) then
- xTextWindow(xWin).doEditMenu(itemNum);
- end;
- end;
-
- procedure DoOtherMenu (menuNum, itemNum: integer);
- { no other menus are used in this program }
- begin
- end;
-
- end.